using System;
using System.Text;

using NUnit.Framework;

using FineCollection.Intf;

namespace FineCollection.Common
{


    public abstract class RSet_Common_test
    {
        protected abstract RSet<T> MakeEmptySet<T>()
            where T : IEquatable<T>, IComparable<T>;

        protected abstract RSet<T> MakeSet<T>(T[] items)
            where T : IEquatable<T>, IComparable<T>;



        [Test]
        public void Test_Empty_Set_Basic()
        {
            RSet<long> s0 = MakeEmptySet<long>();

            Assert.IsTrue(s0.IsEmpty);
            Assert.IsFalse(s0.IsNotEmpty);
            Assert.AreEqual(0, s0.Count);
        }


        [Test]
        public void Test_Empty_Set_Contains()
        {
            RSet<long> s0 = MakeEmptySet<long>();

            Assert.IsFalse(s0.Contains(0));
            Assert.IsFalse(s0.Contains(+1));
            Assert.IsFalse(s0.Contains(-1));
            Assert.IsFalse(s0.Contains(long.MinValue));
            Assert.IsFalse(s0.Contains(long.MaxValue));
        }


        [Test]
        public void Test_Empty_Set_Iterator()
        {
            RSet<long> s0 = MakeEmptySet<long>();
            RIterator<long> it = s0.TakeIterator();

            Assert.IsFalse(it.Next());
        }


        [Test]
        public void Test_Set_1_Basic()
        {
            RSet<long> s1 = MakeSet(new long[] {1111});

            Assert.IsFalse(s1.IsEmpty);
            Assert.IsTrue(s1.IsNotEmpty);
            Assert.AreEqual(1, s1.Count);
        }


        [Test]
        public void Test_Set_1_Contains()
        {
            RSet<long> s1 = MakeSet(new long[] { 1111 });

            Assert.IsFalse(s1.Contains(0));
            Assert.IsTrue (s1.Contains(1111));
            Assert.IsFalse(s1.Contains(long.MinValue));
            Assert.IsFalse(s1.Contains(long.MaxValue));
        }


        [Test]
        public void Test_Set_1_Iterator()
        {
            RSet<long> s1 = MakeSet(new long[] { 1111 });
            RIterator<long> it = s1.TakeIterator();

            Assert.IsTrue( it.Next() );
            Assert.AreEqual(1111, it.Current);
            Assert.IsFalse(it.Next());
        }


        [Test]
        public void Test_Set_3_Basic()
        {
            RSet<long> s3 = MakeSet(new long[] {1111,2222,3333});

            Assert.IsFalse(s3.IsEmpty);
            Assert.IsTrue(s3.IsNotEmpty);
            Assert.AreEqual(3, s3.Count);
        }


        [Test]
        public void Test_Set_3_Contains()
        {
            RSet<long> s3 = MakeSet(new long[] { 1111, 2222, 3333 });

            Assert.IsFalse(s3.Contains(-1));
            Assert.IsTrue (s3.Contains(1111));
            Assert.IsTrue (s3.Contains(2222));
            Assert.IsTrue (s3.Contains(3333));
        }


        [Test]
        public void Test_Set_3_Iterator()
        {
            RSet<long> s3 = MakeSet(new long[] { 1111, 2222, 3333 });
            RIterator<long> it = s3.TakeIterator();

            long[] results = new long[3];

            Assert.IsTrue( it.Next() );
            results[0] = it.Current;
            Assert.IsTrue( it.Next() );
            results[1] = it.Current;
            Assert.IsTrue(it.Next());
            results[2] = it.Current;
            Assert.IsFalse(it.Next());

            Array.Sort(results);

            Assert.AreEqual(1111, results[0]);
            Assert.AreEqual(2222, results[1]);
            Assert.AreEqual(3333, results[2]);
        }


        [Test]
        public void Test_MinMax()
        {
            RSet<int> set = MakeSet(new int[] {int.MinValue, int.MaxValue});    

            Assert.IsTrue(set.Contains(int.MinValue));
            Assert.IsTrue(set.Contains(int.MaxValue));
        }


        [Test]
        public void Test_Same1()
        {
            const string s1 = "abcd";

            StringBuilder s2b = new StringBuilder();
            s2b.Append("ab");
            s2b.Append("cd");
            string s2 = s2b.ToString();

            RSet<string> set = MakeSet(new string[] {s2});

            Assert.IsTrue(set.Contains(s1));
        }
    }


}